﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Datos;

namespace Negocio
{
    public class Pedido : Comprobante
    {
        #region Constantes

        const string ERR_SOURCE = "Pedido";
        const string CLIENTE_CODIGO = "clienteCodigo";
        const string EMPLEADO_LEGAJO = "empleadoLegajo";
        const string ESTADO_ID = "estadoId";

        #endregion

        #region Atributos y Propiedades  

        private Cliente _cliente;
        public Cliente Cliente
        {
            get { return _cliente; }
            set { _cliente = value; MarcarModificado(); }
        }

        private Empleado _empleado;
        public Empleado Empleado
        {
            get { return _empleado; }
            set { _empleado = value; MarcarModificado(); }
        }

        private Estado _estado;
        public Estado Estado
        {
            get
            {
                if (_estado == null && GetClaveONull(ESTADO_ID) != null)
                    _estado = Estado.ObtenerPorId(GetClave(ESTADO_ID).ToString(), typeof(Pedido).Name);
                return _estado;
            }
            set
            {
                SetClave(ESTADO_ID, value != null ? (object)value.Id : null);
                _estado = value;
                MarcarModificado();
            }     
        }

        private List<PedidoDetalle> _pedidoDetalle;
        public List<PedidoDetalle> PedidoDetalle
        {
            get
            {
                if (_pedidoDetalle == null)
                {
                    if (!this.Nuevo)
                        //TODO: Hacer
                    //    _pedidoDetalle = PedidoDetalle.ObtenerPorPedido(this);
                    //else
                        _pedidoDetalle = new List<PedidoDetalle>();
                }
                return _pedidoDetalle;
            }
        }

        public string PedidoString
        {
          get { return _letra + ":" + _puntoVenta + "-" + _numero; }
        }

        #endregion

        public void AgregarDetalle(Articulo articulo, decimal precio, int cantidad)
        {
            PedidoDetalle obj = new PedidoDetalle();
            obj.Pedido = this;
            obj.Articulo = articulo;
            obj.Precio = precio;
            obj.Cantidad = cantidad;
            PedidoDetalle.Add(obj);
        }

        #region Acceso a Datos

        protected override bool LeerDB()
        {
            bool existe = false;
            object[] parametros ={ _letra, _puntoVenta, _numero, null, null, null };
            IDataReader dr = DatosOleDb.DB().ObtenerDataReader("PedidoSFiltro", parametros);
            if (dr.Read())
            {
                CargarDR(dr);
                existe = true;
            }

            dr.Close();
            return existe;
        }

        protected override void InsertDB()
        {
		object[] parametros = new object[] {_letra , _puntoVenta , _numero , _fechaEmision , _observacion , GetClave(CLIENTE_CODIGO) , GetClave(EMPLEADO_LEGAJO) , GetClave(ESTADO_ID) };
            DatosOleDb.DB().TxBegin();
            try
            {
                DatosOleDb.DB().EnviarDatos("PedidoI", ref parametros);
                DatosOleDb.DB().TxCommit();
            }
            catch (System.Data.OleDb.OleDbException)
            {
                DatosOleDb.DB().TxRollback();
                DatosException ex = new DatosException("Ya existe un Pedido con el numero " + PedidoString , ERR_SOURCE);
                throw ex;
            }
            catch (Exception)
            {
                DatosOleDb.DB().TxRollback();
                throw;
            }
        }

        protected override void UpdateDB()
        {
		object[] parametros = new object[] {_letra , _puntoVenta , _numero , _fechaEmision , _observacion , GetClave(CLIENTE_CODIGO) , GetClave(EMPLEADO_LEGAJO) , GetClave(ESTADO_ID) };
            DatosOleDb.DB().TxBegin();
            try
            {
                DatosOleDb.DB().EnviarDatos("PedidoU", ref parametros);
                DatosOleDb.DB().TxCommit();
            }
            catch (System.Data.SqlClient.SqlException)
            {
                DatosOleDb.DB().TxRollback();
                DatosException ex = new DatosException("Ya existe un Pedido con el numero " + PedidoString , ERR_SOURCE);
                throw ex;
            }
            catch (Exception)
            {
                DatosOleDb.DB().TxRollback();
                throw;
            }
        }

        protected override void DeleteDB()
        {
            object[] parametros = new object[] {_letra , _puntoVenta , _numero };
            DatosOleDb.DB().TxBegin();
            try
            {
                DatosOleDb.DB().EnviarDatos("PedidoD", ref parametros);
                DatosOleDb.DB().TxCommit();
            }
            catch (Exception)
            {
                DatosOleDb.DB().TxRollback();
                throw;
            }
        }

        protected override void CargarDR(IDataReader dr)
        {          
            _letra = (Char) dr["letra"];
	        _puntoVenta = (Int32) dr["puntoVenta"];
	        _numero = (Int32) dr["numero"];
	        _fechaEmision = (DateTime) dr["fechaEmision"];
	        _observacion = dr["observacion"].ToString();
	        SetClave(CLIENTE_CODIGO, dr[CLIENTE_CODIGO]);
	        SetClave(EMPLEADO_LEGAJO, dr[EMPLEADO_LEGAJO]);
	        SetClave(ESTADO_ID, dr[ESTADO_ID]);
	        MarcarViejo();
        }

        public override void Validar()
        {
            InconsistenciaException ex = new InconsistenciaException();
            ex.Source = ERR_SOURCE;
            //if (_letra == char.IsLetter) ex.AgregarError("Dato requerido", "Letra");
            if (_puntoVenta == 0) ex.AgregarError("Dato requerido", "Punto de Venta");
            if (_numero == 0) ex.AgregarError("Dato requerido", "Numero");
            ex.Lanzar();
        }

        #endregion

        #region Métodos estaticos de Clase

        public static Pedido ObtenerPorPk(char letra, int puntaVenta, int numero)
        {
            Pedido obj = new Pedido();
            obj._letra = letra;
            obj._puntoVenta = puntaVenta;
            obj._numero = numero;
            if (obj.LeerDB())
            {
                return obj;
            }
            else
            {
                return null;
            }

        }

        public static List<Pedido> ObtenerTodos()
        {
            Pedido obj;
            List<Pedido> lista = new List<Pedido>();
            object[] parametros = { null, null};
            IDataReader dr;
            dr = DatosOleDb.DB().ObtenerDataReader("PedidoSFiltro", parametros);
            while (dr.Read())
            {
                obj = new Pedido();
                obj.CargarDR(dr);             
                lista.Add(obj);
            }
            dr.Close();
            return lista;
        }

        public static List<Pedido> ObtenerPorFiltro(char letra ,int puntoVenta , int numero)
        {
            Pedido obj;
            List<Pedido> lista = new List<Pedido>();
            object[] parametros = { letra, puntoVenta, numero};
            IDataReader dr;
            dr = DatosOleDb.DB().ObtenerDataReader("PedidoSFiltro", parametros);
            while (dr.Read())
            {
                obj = new Pedido();
                obj.CargarDR(dr);             
                lista.Add(obj);
            }
            dr.Close();
            return lista;
        }

        public static int ObtenerNumeroSiguiente(char letra, int puntoVenta)
        {
            int numero = 0;
            object[] parametros = { letra, puntoVenta };
            IDataReader dr;
            dr = DatosOleDb.DB().ObtenerDataReader("PedidoSNumeroSiguiente", parametros);
            while (dr.Read())
            {
                numero = dr["Numero"] != DBNull.Value ? (Int32)dr["Numero"] : 0;
            }
            dr.Close();
            return numero + 1;
        }
        #endregion
    } 
}
